﻿using Common;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DBContext;
using HslCommunication.Profinet.Siemens;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZoneLine.Models;
using ZoneLine.Models.PrintModeConfig;
using ZoneLine.Models.StationConfig;

namespace ZoneLine.ViewModels
{
    public class FormulaSelectViewModel : ObservableObject
    {

        private string _ip;
        private string _remark;
        private string _stationCode;

        private readonly IModelDAL _dal;

        public FormulaSelectViewModel(IModelDAL modelDAL)
        {
            this._dal = modelDAL;
            GetStationList();
        }

        private ObservableCollection<StationConfigBase> stationConfigList;
        /// <summary>
        /// 工站列表
        /// </summary>
        public ObservableCollection<StationConfigBase> StationConfigList
        {
            get { return stationConfigList; }
            set { stationConfigList = value; OnPropertyChanged(); }
        }


        private ObservableCollection<FormulaConfigModel> formulaConfigModelList;
        /// <summary>
        /// 配方详情
        /// </summary>
        public ObservableCollection<FormulaConfigModel> FormulaConfigModelList
        {
            get { return formulaConfigModelList; }
            set { formulaConfigModelList = value; OnPropertyChanged(); }
        }


        private int? _currentPLCUseFormulaNumber;
        /// <summary>
        /// 当前PLC使用配方
        /// </summary>
        public int? CurrentPLCUseFormulaNumber
        {
            get { return _currentPLCUseFormulaNumber; }
            set { _currentPLCUseFormulaNumber = value; OnPropertyChanged(); }
        }

        private int? _currentViewFormulaNumber;
        /// <summary>
        /// 当前查看配方
        /// </summary>
        public int? CurrentViewFormulaNumber
        {
            get { return _currentViewFormulaNumber; }
            set { _currentViewFormulaNumber = value; OnPropertyChanged(); }
        }

        private ObservableCollection<int?> _formulaNumberList;
        /// <summary>
        /// 配方序号列表
        /// </summary>
        public ObservableCollection<int?> FormulaNumberList
        {
            get { return _formulaNumberList; }
            set { _formulaNumberList = value; OnPropertyChanged(); }
        }

        private FormulaDBConfigModel _formulaDBConfigModel;
        /// <summary>
        /// 配方数据点位
        /// </summary>
        public FormulaDBConfigModel FormulaDBConfigModel
        {
            get { return _formulaDBConfigModel; }
            set { _formulaDBConfigModel = value; OnPropertyChanged(); }
        }


        public RelayCommand<StationConfigBase> StationConfigSelectedCmd => new RelayCommand<StationConfigBase>((obj) =>
        {
            if (obj != null)
            {
                _ip = obj.Ip; 
                _remark = obj.Remark;
                _stationCode = obj.StationCode;
                GetFormulaWriteDBAddrList(_ip);//获取当前工位配方点位信息
                GetCurrentStationUseFormula(_ip);//获取当前工位使用的配方
                GetFormulaConfigModelList(_ip, CurrentPLCUseFormulaNumber);//获取配方数据项
            }
        });

        //保存
        public RelayCommand SaveCmd => new RelayCommand(() =>
        {
            //Task.Run(async () =>
            //{
            //    var res = WriteData(FormulaDBConfigModel.FormuladSaveAddr, true);
            //    await Task.Delay(500);
            //    res = WriteData(FormulaDBConfigModel.FormuladSaveAddr, false);
            //    if (res)
            //    {
            //        HandyControl.Controls.MessageBox.Success("保存成功！", "温馨提示");
            //    }
            //});
        });

        //减少
        public RelayCommand ReduceCmd => new RelayCommand(() =>
        {
            if (CurrentViewFormulaNumber <= 1)
            {
                return;
            }
            else
            {
                CurrentViewFormulaNumber--;
                GetFormulaConfigModelList(_ip, CurrentViewFormulaNumber);
                //Task.Run(async () =>
                //{
                //    WriteData(FormulaDBConfigModel.FormuladReduceAddr, true);
                //    await Task.Delay(500);
                //    WriteData(FormulaDBConfigModel.FormuladReduceAddr, false);
                //});
            }
        });

        //添加
        public RelayCommand AddCmd => new RelayCommand(() =>
        {
            if (CurrentViewFormulaNumber >= FormulaNumberList.Count)
            {
                return;
            }
            else
            {
                CurrentViewFormulaNumber++;
                GetFormulaConfigModelList(_ip, CurrentViewFormulaNumber);
                //Task.Run(async () =>
                //{
                //    WriteData(FormulaDBConfigModel.FormuladAddAddr, true);
                //    await Task.Delay(500);
                //    WriteData(FormulaDBConfigModel.FormuladAddAddr, false);
                //});
            }
        });

        //下载
        public RelayCommand DownloadCmd => new RelayCommand(() =>
        {
            var mbox = HandyControl.Controls.MessageBox.Ask("确定当前设备为手动模式，并且下载当前选择的配方数据吗？", "温馨提示");
            if (mbox == System.Windows.MessageBoxResult.OK)
            {
                Task.Run(async () =>
                {
                    bool res = false;
                    res = WriteData(FormulaDBConfigModel.FormuladNumberAddr, CurrentViewFormulaNumber.Value);
                    await Task.Delay(500);
                    WriteData(FormulaDBConfigModel.FormuladDownloadAddr, true);
                    await Task.Delay(500);
                    WriteData(FormulaDBConfigModel.FormuladDownloadAddr, false);
                    if (res)
                    {
                        GetCurrentStationUseFormula(_ip);//重新获取一次PLC配方
                        if (CurrentPLCUseFormulaNumber != CurrentViewFormulaNumber.Value)
                        {
                            HandyControl.Controls.MessageBox.Error("下载配方失败，读取不一致，请检查设备是否为在线模式！", "温馨提示");
                            return;
                        }
                        //缓存起来，如存在则先移除在新增
                        if (Cache.CurrentFormula.Where(o => o.IP == _ip).Count() > 0)
                        {
                            Cache.CurrentFormula.Remove(Cache.CurrentFormula.Where(o => o.IP == _ip).FirstOrDefault());
                        }
                        FormulaItem formulaItem = new FormulaItem();
                        formulaItem.IP = _ip;
                        formulaItem.StationCode = _stationCode;
                        formulaItem.Remark = _remark;
                        formulaItem.FormulaNumber = CurrentPLCUseFormulaNumber.Value;
                        formulaItem.Model = ModelEnum.LX;


                        if (_ip == "192.168.10.10" || _ip == "192.168.10.25") //后减
                        {
                            var productType = FormulaConfigModelList.Where(o => o.FieldDescription == "配方名")?.FirstOrDefault().FieldValue;
                            if (productType != null && productType != "")
                            {
                                formulaItem.CurrentProductType = productType;
                            }

                            var leftRight = FormulaConfigModelList.Where(o => o.FieldDescription == "产品型号").FirstOrDefault().FieldValue.ToUpper();
                            if (leftRight == "L")
                            {
                                formulaItem.WorkDirection = Common.WorkDirectionEnum.Left;
                            }
                            else if (leftRight == "R")
                            {
                                formulaItem.WorkDirection = Common.WorkDirectionEnum.Right;
                            }
                            else
                            {
                                formulaItem.WorkDirection = Common.WorkDirectionEnum.None;
                            }
                        }
                        else if (_ip == "192.168.10.75" || _ip == "192.168.10.90" || _ip == "192.168.10.105")//前减-弹簧测高 前减-上支撑螺母拧紧工位(左) | 前减-上支撑螺母拧紧工位(右)
                        {
                            //工作左右件选择 X04(0是左件，1是右件) W04(1是左件，0是右件)
                            var productType = FormulaConfigModelList.Where(o => o.FieldDescription == "产品型号")?.FirstOrDefault().FieldValue;
                            if (productType != null && productType != "")
                            {
                                formulaItem.CurrentProductType = productType;
                            }

                            var formulaName = FormulaConfigModelList.Where(o => o.FieldDescription.Contains("工作左右件选择"))?.FirstOrDefault().FieldValue;
                            if (formulaName != null && formulaName != "")
                            {
                                if (productType == "W04" && formulaName == "1")
                                {
                                    formulaItem.WorkDirection = Common.WorkDirectionEnum.Left;
                                }
                                else if (productType == "W04" && formulaName == "0")
                                {
                                    formulaItem.WorkDirection = Common.WorkDirectionEnum.Right;
                                }
                                else if (productType == "X04" && formulaName == "0")
                                {
                                    formulaItem.WorkDirection = Common.WorkDirectionEnum.Left;
                                }
                                else if (productType == "X04" && formulaName == "1")
                                {
                                    formulaItem.WorkDirection = Common.WorkDirectionEnum.Right;
                                }
                            }
                        }
                        //else if (_ip == "192.168.10.90" || _ip == "192.168.10.105")//前减-上支撑螺母拧紧工位(左) | 前减-上支撑螺母拧紧工位(右)
                        //{
                        //    //工作左右件选择 X04(0是左件，1是右件) W04(1是左件，0是右件)
                        //    var productType = FormulaConfigModelList.Where(o => o.FieldDescription == "产品型号")?.FirstOrDefault().FieldValue;
                        //    if (productType != null && productType != "")
                        //    {
                        //        formulaItem.CurrentProductType = productType;
                        //    }

                        //    var formulaName = FormulaConfigModelList.Where(o => o.FieldDescription.Contains("工作左右件选择"))?.FirstOrDefault().FieldValue;
                        //    if (formulaName != null && formulaName != "")
                        //    {
                        //        if (formulaName == "0")
                        //        {
                        //            formulaItem.WorkDirection = Common.WorkDirectionEnum.Left;
                        //        }
                        //        else if (formulaName == "1")
                        //        {
                        //            formulaItem.WorkDirection = Common.WorkDirectionEnum.Right;
                        //        }
                        //    }
                        //}
                        Cache.CurrentFormula.Add(formulaItem);
                        HandyControl.Controls.MessageBox.Success("下载配方成功！", "温馨提示");
                    }
                    else {
                        HandyControl.Controls.MessageBox.Success("下载配方失败！", "温馨提示");
                    }
                });
            }
        });



        /// <summary>
        /// 获取工站列表
        /// </summary>
        private void GetStationList()
        {
            StationConfigList = new ObservableCollection<StationConfigBase>();
            if (Cache.IsQopStaion)
            {
                //var obj3 = _dal.GetModelList<QOP006StationConfig>(o => 1 == 1).FirstOrDefault();
                var obj4 = _dal.GetModelList<QOP010StationConfig>(o => 1 == 1).FirstOrDefault();
                //var obj5 = _dal.GetModelList<QOP020StationConfig>(o => 1 == 1).FirstOrDefault();
                var obj6 = _dal.GetModelList<QOP050LStationConfig>(o => 1 == 1).FirstOrDefault();
                var obj7 = _dal.GetModelList<QOP050RStationConfig>(o => 1 == 1).FirstOrDefault();
                //StationConfigList.Add(obj3);
                //StationConfigList.Add(obj5);
                StationConfigList.Add(obj4);
                StationConfigList.Add(obj6);
                StationConfigList.Add(obj7);
            }
            else if (Cache.IsHopStaion)
            {
                var obj1 = _dal.GetModelList<HOP010StationConfig>(o => 1 == 1).FirstOrDefault();
                var obj2 = _dal.GetModelList<HOP040StationConfig>(o => 1 == 1).FirstOrDefault();
                StationConfigList.Add(obj1);
                StationConfigList.Add(obj2);
            }
            foreach (var item in StationConfigList)
            {
                item.Remark = $"{item.StationCode}{item.Remark}";
            }
        }

        /// <summary>
        /// 获取工作配置信息
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="formulaNumber"></param>
        private void GetFormulaConfigModelList(string ip = "", int? formulaNumber = null)
        {
            var list = new List<FormulaConfigModel>();
            if (ip != "")
            {
                list = _dal.GetModelList<FormulaConfigModel>(o => o.PlcIp == ip);
            }
            else
            {
                list = _dal.GetModelList<FormulaConfigModel>(o => true);
            }

            if (list.Count > 0)
            {
                FormulaNumberList = new ObservableCollection<int?>(list.Select(o => o.Number).Distinct().ToList());
                if (formulaNumber.HasValue)
                {
                    CurrentViewFormulaNumber = formulaNumber;
                    FormulaConfigModelList = new ObservableCollection<FormulaConfigModel>(list.Where(o => o.Number == formulaNumber).ToList());
                }
                else
                {
                    CurrentViewFormulaNumber = FormulaNumberList.FirstOrDefault().Value;
                    FormulaConfigModelList = new ObservableCollection<FormulaConfigModel>(list.Where(o => o.Number == CurrentViewFormulaNumber).ToList());
                }
            }
            else
            {
                FormulaNumberList = default;
                CurrentViewFormulaNumber = default;
                FormulaConfigModelList = default;
            }
        }

        /// <summary>
        /// 获取当前工站使用的配方号
        /// </summary>
        private void GetCurrentStationUseFormula(string ip)
        {
            try
            {
                SiemensS7Net _client = new SiemensS7Net(SiemensPLCS.S1200);
                _client.IpAddress = ip;
                _client.SetPersistentConnection();
                _client.Port = 102;
                var readContent = _client.ReadInt16(FormulaDBConfigModel.FormuladPLCUseAddr)?.Content;
                if (readContent != null)
                {
                    var readRlt = Convert.ToInt32(readContent);//读取当前配方地址
                    CurrentPLCUseFormulaNumber = readRlt;
                }
                else
                {
                    HandyControl.Controls.MessageBox.Error("获取PLC配方失败！","温馨提示");
                }
                _client.ConnectClose();
            }
            catch (Exception ex)
            {
                HandyControl.Controls.MessageBox.Error(ex.Message, "温馨提示");
            }
        }

        /// <summary>
        /// 获取工作配方数据点位
        /// </summary>
        /// <param name="ip"></param>
        private void GetFormulaWriteDBAddrList(string ip)
        {
            var  formulaDBConfig = _dal.GetModel<FormulaDBConfigModel>(o => o.PlcIp == ip);
            FormulaDBConfigModel = formulaDBConfig;
        }

        private bool WriteData(string address, bool data)
        {
            bool res = false;
            try
            {
                SiemensS7Net _client = new SiemensS7Net(SiemensPLCS.S1200);
                _client.IpAddress = _ip;
                _client.SetPersistentConnection();
                _client.Port = 102;
                Logger.Log.Debug($"配方板块,上位机下发{address}点位数据,参数:{data}");
                var rls = _client.Write(address, data);
                Logger.Log.Debug($"配方板块,上位机下发{address}点位数据,结果:{rls.IsSuccess}");
                _client.ConnectClose();
                res = rls.IsSuccess;
            }
            catch (Exception ex)
            {
                HandyControl.Controls.MessageBox.Error(ex.Message);
            }
            return res;
        }

        private bool WriteData(string address, int data)
        {
            bool res = false;
            try
            {
                SiemensS7Net _client = new SiemensS7Net(SiemensPLCS.S1200);
                _client.IpAddress = _ip;
                _client.SetPersistentConnection();
                _client.Port = 102;
                Logger.Log.Info($"配方板块，上位机下发{address}点位数据，参数:{data}");
                var rls = _client.Write(address, (short)data);
                Logger.Log.Info($"配方板块，上位机下发{address}点位数据，参数:{data}，结果:{rls.IsSuccess}");
                _client.ConnectClose();
                res = rls.IsSuccess;
                var readValue = _client.ReadInt16(address).Content;
                Logger.Log.Info($"配方板块，从下位机读取{address}点位数据，结果:{readValue}");
            }
            catch (Exception ex)
            {
                HandyControl.Controls.MessageBox.Error(ex.Message, "温馨提示");
                //throw;
            }
            return res;
        }

    }


}
